package gitobject;

import java.awt.font.TextMeasurer;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;

import Index.Index;
import fileoperation.FileReader;
import sha1.SHA1;
import repository.Repository;
import zlib.ZLibUtils;

import Index.TreeNode;

/**
 * commit包含其中所有文件所形成的一棵树，以及提交信息（提交者，提交时间等等）
 */
public class Commit extends GitObject implements Serializable{
    protected String tree; 		// the sha1 value of present committed tree
    protected String parent; 	// the sha1 value of the parent commit
    protected String author; 	// the author's name and timestamp
    protected String committer; // the committer's info
    protected String message; 	// the commit memo
    public TreeNode indexTree;  // the root node of present index
    private String branchName;  // the name of present branch

    public String getParent(){return parent;}
    public String getTree(){return tree;}
    public String getAuthor(){return author;}
    public String getCommitter(){return committer;}
    public String getMessage(){return message;}

    public Commit() throws Exception {

    }
    /**
     * Construct a commit directly from a file.
     * @param message 参数在git commit命令里创建
     *
     * @throws Exception
     */
    public Commit(String message)  throws Exception {
        this.fmt = "commit"; 	//type of object
        this.author = "RaoMaoyuan && XieBo";
        this.committer = "HuangRuixuan";
        Index index = new Index();

        TreeNode indexTree = index.getIndexTree();

        if(!indexTree.getpath().equals(new File(".").getCanonicalPath() + File.separator+ ".jit" + File.separator + "index") ){
            TreeNode tem = new TreeNode();
            ArrayList<TreeNode> list = tem.getChildren();
            list.add(indexTree);
            tem.setChildren(list);
            tem.setpath(new File(".").getCanonicalPath() + File.separator+ ".jit" + File.separator + "index");
            tem.setType("tree");
            tem.setBase("tree");
            String value = indexTree.toString();
            String id = SHA1.getHash(value);
            tem.setId(id);
            indexTree = tem;
            index.setIndexTree(indexTree);
        }
        this.indexTree = index.getIndexTree();
        if(index != null) {
            this.tree = index.getIndexTree().getId();
        }
        this.parent = getLastCommit() == null ? "" : getLastCommit(); //null means there is no parent commit.
        this.message = message;
        this.tree = indexTree.getId();
        this.value = "tree " + this.tree + "\nparent " + this.parent+ "\nauthor " + this.author + "\ncommitter " + this.committer + "\n" + this.message;
        File HEAD = new File(new File(".").getCanonicalPath() + File.separator+ ".jit" + File.separator + "HEAD");
        if (getValue(HEAD).length() == 0){
            return;
        }
        this.branchName = getValue(HEAD).substring(16);
        key = genKey();
    }
    


    public String getBranchName() {
        return branchName;
    }

    public void setBranchName(String branchName) {
        this.branchName = branchName;
    }

    /**
     * Generate the hash value of this commit.
     * @return key
     * */
    public String genKey() throws Exception {
        key = SHA1.getHash(value);
        return key;
    }




    /**
     * Get the parent commit from the HEAD file.
     * @return
     * @throws IOException
     */
    public static String getLastCommit() throws IOException {
        File HEAD = new File(new File(".").getCanonicalPath() + File.separator+ ".jit"  + File.separator + "HEAD");
        if (getValue(HEAD).length() == 0){
            return null;
        }
        String path = getValue(HEAD).substring(5).replace("\n", "");
        File branchFile = new File(new File(".").getCanonicalPath() + File.separator+ ".jit"  + File.separator + path);

        if (branchFile.isFile()) {
            return getValue(branchFile);
        } else {
            return null;
        }
    }

    public void setLastCommit() throws Exception {
        FileOutputStream fos = null;
        File HEAD = new File(new File(".").getCanonicalPath() + File.separator+ ".jit"  + File.separator + "HEAD");
        fos = new FileOutputStream(HEAD);
        String str = "ref: refs/heads/" + this.branchName;
        fos.write(str.getBytes(StandardCharsets.UTF_8));
        File branch = new File(new File(".").getCanonicalPath() + File.separator+ ".jit"  + File.separator + "refs" + File.separator + "heads" + File.separator + branchName);
        fos = new FileOutputStream(branch);
        key = genKey();
        fos.write(this.key.getBytes(StandardCharsets.UTF_8));
        if(fos != null) {
            fos.close();
        }
    }

    @Override
    public String toString() {
        return "ID " + key + '\n' + "tree "+tree + '\n' + "parent " + parent +'\n' + "author " + author + '\n' + "committer " + committer + '\n' + "\n" + message;
    }
}

